#include "midea_base_scroll_tool.h"
#include <stdlib.h>

// 将子UI从from_index设置到to_index
// 并且保持其他子UI位置不变
void midea_obj_child_move_to_index(lv_obj_t *obj, uint32_t from_index, uint32_t to_index)
{
    uint32_t count = lv_obj_get_child_cnt(obj);
    if (to_index >= count || from_index >= count || from_index == to_index)
    {
        return;
    }

    lv_obj_t *from_obj = obj->spec_attr->children[from_index];
    lv_obj_t *to_obj = obj->spec_attr->children[to_index];
    if (from_index > to_index)
    {
        // 大于to_index && 小于from_index 之间的元素后移
        for (uint32_t i = from_index; i > to_index; i--)
        {
            obj->spec_attr->children[i] = obj->spec_attr->children[i - 1];
        }
        obj->spec_attr->children[to_index] = from_obj;
    }
    else
    {
        // 大于from_index && 小于to_index 之间的元素前移
        //  lv_obj_t *from_obj = obj->spec_attr->children[from_index];
        for (uint32_t i = from_index; i < to_index; i++)
        {
            obj->spec_attr->children[i] = obj->spec_attr->children[i + 1];
        }
        obj->spec_attr->children[to_index] = from_obj;
    }
    // 发送子元素变更事件
    lv_event_send(obj, LV_EVENT_CHILD_CHANGED, from_obj);
    lv_event_send(obj, LV_EVENT_CHILD_CHANGED, to_obj);
}

void midea_obj_del_core(lv_obj_t *obj)
{
    /*Let the user free the resources used in `LV_EVENT_DELETE`*/
    lv_res_t res = lv_event_send(obj, LV_EVENT_DELETE, NULL);
    if (res == LV_RES_INV)
        return;

    /*Recursively delete the children*/
    lv_obj_t *child = lv_obj_get_child(obj, 0);
    while (child)
    {
        midea_obj_del_core(child);
        child = lv_obj_get_child(obj, 0);
    }

    lv_group_t *group = lv_obj_get_group(obj);

    /*Reset all input devices if the object to delete is used*/
    lv_indev_t *indev = lv_indev_get_next(NULL);
    while (indev)
    {
        if (indev->proc.types.pointer.act_obj == obj || indev->proc.types.pointer.last_obj == obj)
        {
            lv_indev_reset(indev, obj);
        }
        if (indev->proc.types.pointer.last_pressed == obj)
        {
            indev->proc.types.pointer.last_pressed = NULL;
        }

        if (indev->group == group && obj == lv_indev_get_obj_act())
        {
            lv_indev_reset(indev, obj);
        }
        indev = lv_indev_get_next(indev);
    }

    /*All children deleted. Now clean up the object specific data*/
    _lv_obj_destruct(obj);

    /*Remove the screen for the screen list*/
    if (obj->parent == NULL)
    {
        lv_disp_t *disp = lv_obj_get_disp(obj);
        uint32_t i;
        /*Find the screen in the list*/
        for (i = 0; i < disp->screen_cnt; i++)
        {
            if (disp->screens[i] == obj)
                break;
        }

        uint32_t id = i;
        for (i = id; i < disp->screen_cnt - 1; i++)
        {
            disp->screens[i] = disp->screens[i + 1];
        }
        disp->screen_cnt--;
        disp->screens = lv_mem_realloc(disp->screens, disp->screen_cnt * sizeof(lv_obj_t *));
    }
    /*Remove the object from the child list of its parent*/
    else
    {
        uint32_t id = lv_obj_get_index(obj);
        uint32_t i;
        for (i = id; i < obj->parent->spec_attr->child_cnt - 1; i++)
        {
            obj->parent->spec_attr->children[i] = obj->parent->spec_attr->children[i + 1];
        }
        obj->parent->spec_attr->child_cnt--;
        obj->parent->spec_attr->children = lv_mem_realloc(obj->parent->spec_attr->children,
                                                          obj->parent->spec_attr->child_cnt * sizeof(lv_obj_t *));
    }

    /*Free the object itself*/
    lv_mem_free(obj);
}
// 删除指定索引范围的子UI
void midea_delete_child_from_range(lv_obj_t *obj, int32_t start_index, int32_t end_index, bool free_user_data)
{
    lv_obj_invalidate(obj);
    for (int32_t i = start_index; i <= end_index; i++)
    {
        lv_obj_t *more_cell = lv_obj_get_child(obj, start_index);
        if (more_cell == NULL)
        {
            break;
        }
        if (free_user_data && more_cell->user_data != NULL)
        {
            // 释放ui_type记录
            lv_mem_free(more_cell->user_data);
            more_cell->user_data = NULL;
        }
        midea_obj_del_core(more_cell);
    }
    lv_obj_readjust_scroll(obj, LV_ANIM_OFF);
    LV_ASSERT_MEM_INTEGRITY();
}

// 从指定索引开始删除所有之后的子UI
void midea_delete_child_from_index(lv_obj_t *obj, int32_t index, bool free_user_data)
{
    lv_obj_invalidate(obj);

    lv_obj_t *child = lv_obj_get_child(obj, index);
    while (child)
    {
        if (free_user_data && child->user_data != NULL)
        {
            // 释放ui_type记录
            lv_mem_free(child->user_data);
            child->user_data = NULL;
        }

        midea_obj_del_core(child);
        child = lv_obj_get_child(obj, index);
    }
    lv_obj_readjust_scroll(obj, LV_ANIM_OFF);
    LV_ASSERT_MEM_INTEGRITY();
}

// 获取lv_obj_t的scroll容纳的size高度或宽度
lv_coord_t midea_obj_scroll_length(lv_obj_t *obj, bool is_vertical, lv_coord_t scroll_end)
{
    // LV_ASSERT_OBJ(obj, MY_CLASS);
    // 没有子UI时返回100
    lv_coord_t child_res = 100;
    uint32_t child_cnt = lv_obj_get_child_cnt(obj);
    if (child_cnt == 0)
    {
        return child_res;
    }

    for (int32_t i = child_cnt - 1; i >= 0; i--)
    {
        lv_obj_t *child = obj->spec_attr->children[i];
        if (is_vertical)
        {
            if (child->coords.y2 <= 0)
            {
                continue;
            }
            lv_coord_t bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN);
            lv_coord_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN);
            child_res = LV_MAX(child_res, child->coords.y2 + bottom + border_width - obj->coords.y1 + scroll_end);
            break;
        }
        else
        {
            if (child->coords.x2 <= 0)
            {
                continue;
            }
            lv_coord_t right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN);
            lv_coord_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN);
            child_res = LV_MAX(child_res, child->coords.x2 + right + border_width - obj->coords.x1 + scroll_end);
            break;
        }
    }

    return child_res;
}

// 获取在lv_obj_t中 scroll_target坐标 附近的一个cell 非精确
int32_t midea_obj_child_id_of_scroll_position(lv_obj_t *obj, bool is_vertical, lv_coord_t scroll_end, lv_coord_t scroll_target)
{
    uint32_t child_cnt = lv_obj_get_child_cnt(obj);
    for (int32_t i = child_cnt - 1; i >= 0; i--)
    {
        lv_obj_t *child = obj->spec_attr->children[i];
        if (is_vertical)
        {
            if (child->coords.y1 <= 0)
            {
                // 容错处理
                // 滑动快的时候coords.y1可能为负数
                //  printf("midea_list_scroll_size child->coords.y1 <= 0\n");
                return -1;
            }
            if (child->coords.y1 - obj->coords.y1 + scroll_end <= scroll_target && child->coords.y2 - obj->coords.y1 + scroll_end > scroll_target)
            {
                return i;
            }
        }
        else
        {
            if (child->coords.x1 <= 0)
            {
                // 容错处理
                return -1;
            }
            if (child->coords.x1 - obj->coords.x1 + scroll_end <= scroll_target && child->coords.x2 - obj->coords.x1 + scroll_end > scroll_target)
            {
                return i;
            }
        }
    }

    return -1;
}
